#title: 你都可以注入什么
#index:0,2
#author:zozoh(zozohtnt@gmail.com)
--------------------------------------------------------------------------------------------------------
从哪里注入？

	你可以向对象注入值的位置有两个
	 # 构造函数参数
	 # 属性
	
	向构造函数里注入参数
		
		你的 JSON 配置文件会是这样
		{{{
		{
			xb : {
				type : 'nutz.demo.ioc.book.Pet',
				args : ['XiaoBai']
			}
		}
		}}}
		args 的值时一个数组，里面每一个元素都将对应构造函数的一个参数。当然，你
		必须确保你得有这样的构造函数。每个参数按照 JSON 的规定，是用半角逗号分隔的。
		
	向属性注入参数
		你的 JSON 配置文件会是这样
		{{{
		{
			xb : {
				type : 'nutz.demo.ioc.book.Pet',
				fields : {
					name : 'XiaoBai'
				}
			}
		}
		}}}
		如果你不需要写 type，那么你可以用简写模式:
		{{{
		{
		xb : { name: 'XiaoBai'	}
		}
		}}}
--------------------------------------------------------------------------------------------------------
值可以不仅是字符串
	是的，它还可以是

	布尔
		{{{
		{
			xb : { dead: true }
		}
		}}}

	数字
		{{{
		{
			xb : { age: 24 }
		}
		}}}
	
	内部对象
		{{{
		{
			xb : {
				friend: {
					type : 'nutz.demo.ioc.book.Pet',
					fields : {name : 'XiaoHei'}
				}
			}
		}
		}}}
		关于内部对象 [inner_object.man 请看这里]
	
	引用
		{{{
		{
			xb : { friend: {refer: 'XiaoBai' } }
		}
		}}}
		
		`{refer : '另外一个对象在容器中的名称'}` 将会得到容器中另外一个对象
		
	容器自身	
		{{{
		{
			xb : { myIoc : {refer: '$Ioc'} }
		}
		}}}
		一种特殊的引用，大小写不敏感，值就是 Ioc 容器本身
	
	对象的名称
		{{{
		{
			xb : { myIoc : {refer: '$Name'} }
		}
		}}}
		一种特殊的引用，大小写不敏感，值就是对象的名称，即 "xb"
	
	容器上下文
		{{{
		{
			xb : { myIoc : {refer: '$Context'} }
		}
		}}}
		一种特殊的引用，大小写不敏感，值就是当前容器的上下文环境接口 org.nutz.ioc.IocContext
	
	环境变量
		{{{
		{
			xb : { name : {env : "JAVA_HOME"} }
		}
		}}}
		`{env : '环境变量名'}` 将会得到系统中环境变量的值
		
		从1.b.53开始, env及sys支持数组了, 例如需要JAVA_HOME下面的/bin/java的路径,可以写为
		
		{{{
		{
			xb : { name : {env : ["JAVA_HOME", "/bin/java"]} }
		}
		}}}
		
		注入的属性值类似于 /opt/jdk8/bin/java
		
		如果某个环境变量不存在的时候当成空字符串,那么,在前面加个感叹号
		
		{{{
		{
			xb : { name : {env : ["!JAVA_HOME", "/bin/java"]} }
		}
		}}}
		
		当JAVA_HOME不存在时,就会输出 /bin/java
		
		同时也支持默认值哦,用冒号分割
		
		{{{
		{
			xb : { name : {env : ["!JAVA_HOME:/opt/jdk6", "/bin/java"]} }
		}
		}}}
	
	文件
		{{{
		{
			xb : { profile : {file : "/home/zozoh/tmp/name.txt"} }
		}
		}}}
		`{file : '文件路径'}` 可以是绝对路径，也可以是 CLASSPATH 中的路径
	
	数组或容器
		如果你对象某个字段是数组，集合，或者 Map， 用 JSON 可以很自然为其设置值，不是吗？
	
	----------------------------------------------------------------------------------------------------
	Java 调用
		这是个极度灵活的注入方式，它几乎可以让你 {*做任何事情}。 因为它允许你直接调用一个 JAVA 函数。
		
		更详细的说明，请参看 [https://github.com/nutzam/nutz/blob/master/src/org/nutz/ioc/val/JavaValue.java org.nutz.ioc.val.JavaValue] 的 JDoc
		
		下面只是列出主要的几种应用方式
		
		静态属性
			{{{
			{
				xb : { oneField : {java: 'com.my.SomeClass.staticPropertyName'} }
			}
			}}}
		静态函数
			{{{
			{
				xb : { oneField : {java: 'com.my.SomeClass.someFunc'} }
			}
			}}}
		带参数的静态函数
			{{{
			{
				xb : { oneField : {java: 'com.my.SomeClass.someFunc("p1",true)'} }
			}
			}}}
			参数可以是任何种类的值
			
		容器中的对象
			{{{
			{
				xb : { oneField : {java: '$xh'} } ,
				xh : { name : 'XiaoHei'}
			}
			}}}
		容器对象某个属性
			{{{
			{
				xb : { oneField : {java: '$xh.name'} } ,
				xh : { name : 'XiaoHei'}
			}
			}}}
		容器对象某个方法的返回值
			{{{
			{
				xb : { oneField : {java: '$xh.getXXX()'} } ,
				xh : { name : 'XiaoHei'}
			}
			}}}
		容器对象某个方法的返回值，带参数
			{{{
			{
				xb : { oneField : {java: '$xh.getXXX("some string", true, 34)'} } ,
				xh : { name : 'XiaoHei'}
			}
			}}}
			参数可以是任何种类的值
--------------------------------------------------------------------------------------------------------
你可以增加自己的特殊类型

	从上面你可以看到 JSON 语法的好处，非常轻巧
	 * 文件  -- `{file: '路径'}`
	 * 环境变量  -- `{env: '环境变量名'}`
	 * 引用  -- `{refer: '对象名'}`
	 * JAVA   -- `{java: '$对象名.方法名(参数1, 参数2)'}`
	
	还可以更多吗？
	
	是的，你完全可以扩展，比如你如果想支持一种新的类型：
	{{{
	oneField : {scan : '扫描仪地址'}
	}}}
	如何支持这种新的值的类型呢？
	
	实现一个扩展接口
		实现  org.nutz.ioc.ValueProxyMaker 接口：
		{{{
		package nutz.demo.ioc.book;

		import org.nutz.ioc.IocMaking;
		import org.nutz.ioc.ValueProxy;
		import org.nutz.ioc.ValueProxyMaker;
		import org.nutz.ioc.meta.IocValue;
		import org.nutz.lang.Lang;

		public class ScanValueProxyMaker implements ValueProxyMaker {

			public ValueProxy make(IocMaking ing, IocValue iv) {
				if ("scan".equals(iv.getType())) {
					final String address = iv.getValue().toString();

					return new ValueProxy() {
						public Object get(IocMaking ing) {
							// 根据 address 创建一个对象
							throw Lang.noImplement();
						}

					};
				}
				return null;
			}
			
			public String[] supportedTypes() {
				return new String[]{"scan"};
			}
		}
		}}}
	添加到 Ioc 容器中
		{{{
		Ioc2 ioc = new NutIoc(new JsonLoader("path/path/name.js"));
		ioc.addValueProxyMaker(new ScanValueProxyMaker());
		
		// 下面，你就可以正常使用 Ioc 接口了
		}}}
		{#F00;*注意}，这里使用的是 Ioc2 接口，它继承自 Ioc 接口，提供了更高级的方法
	
	
	
	
	
	
	